#include<iostream>
using namespace std;
/*
学习目标：
掌握类模板配合友元函数的类内和类外实现

全局函数类内实现 - 直接在类内声明友元即可
全局函数类外实现 - 需要提前让编译器知道全局函数的存在
*/
template<class T1,class T2>
class Person;
//类外实现
template<class T1,class T2>
void printPerson2(Person<T1,T2> p)
{
    cout<<"类外实现"<<"name="<<p.m_Name<<" age="<<p.m_Age<<endl;
}
template<class T1,class T2>
class Person
{
    //全局函数 类内实现，加个friend，就变成全局函数了
    friend void printPerson(Person<T1,T2> p)
    {
        cout<<"name="<<p.m_Name<<" age="<<p.m_Age<<endl;
    }
    //全局函数 类外实现
    //加空模板参数列表
    //如果全局函数是类外实现的话，需要让编译器提前知道这个函数的存在
    friend void printPerson2<>(Person<T1,T2> p);//声明要跟实现对上，实现是模板函数，声明也要是
public:
    Person(T1 name,T2 age)
    {
        this->m_Name=name;
        this->m_Age=age;
    }
private:
    T1 m_Name;
    T2 m_Age;
};

//
void test01()
{
    Person<string,int> p("tom",30);
    printPerson(p);
    printPerson2(p);
}
int main()
{
    test01();
}
/*
总结：
建议全局函数做类内实现，用法简单，而且编译器可以直接识别
*/